import { createRootAst } from "./ast";
import { Action, ActionVisitor } from "./base";
import { LiveRoomInfo, getLiveRoomInfo } from "./liveRoom";
import { getLiveRoomLink } from "./liveRoomLink";
import { getLiveRoomRedPackets } from "./red/LiveRoomRedPacketInfoVisitor";
import { kwaiLiveaggregatesquare } from "./schema";
import { PACKAGES, getDeviceUuid, httpPost } from "./utils";
export interface StartPayload {
    pkg: string;
}
export class StartAction extends Action<StartPayload> {
    type: `visitStart` = `visitStart`;
    title: string = `抓包开始`
}
export class EndAction extends Action<void> {
    type: `visitEnd` = `visitEnd`;
    title: string = `抓包结束`
}

export class StopAction extends Action<void> {
    type: `visitStop` = `visitStop`;
    title: string = `停止`
}

export class NextAction extends Action<void> {
    type: `visitNext` = `visitNext`;
    title: string = `下一个`
}

/**
 * 获取直播间信息
 */
export interface RoomInfo { }
export class RoomInfoAction extends Action<RoomInfo>{
    type: `visitRoomInfo` = `visitRoomInfo`;
    title: string = `获取房间信息`
}
export class RoomInfoSuccessAction extends Action<LiveRoomInfo>{
    type: `visitRoomInfoSuccess` = `visitRoomInfoSuccess`;
    title: string = `获取房间信息成功`
}
export class RoomInfoFailAction extends Action<void>{
    type: `visitRoomInfoFail` = `visitRoomInfoFail`;
    title: string = `获取房间信息失败`
}
/**
 * 获取直播间红包信息
 */
export interface RedInfo { }

export class RedInfoAction extends Action<RoomInfo>{
    type: `visitRedInfo` = `visitRedInfo`;
    title: string = `获取红包信息`
}
export class RedInfoSuccessAction extends Action<RedInfo>{
    type: `visitRedInfoSuccess` = `visitRedInfoSuccess`;
    title: string = `获取红包信息成功`
}
export class RedInfoFailAction extends Action<void>{
    type: `visitRedInfoFail` = `visitRedInfoFail`;
    title: string = `获取红包信息失败`
}
/**
 * 房间连接
 */
export interface RoomLinkInfo { }

export class RoomLinkAction extends Action<RoomLinkInfo>{
    type: `visitRoomLink` = `visitRoomLink`;
    title: string = `获取房间连接`
}
export class RoomLinkSuccessAction extends Action<RoomLinkInfo>{
    type: `visitRoomLinkSuccess` = `visitRoomLinkSuccess`;
    title: string = `获取房间连接成功`
}

export class RoomLinkFailAction extends Action<void>{
    type: `visitRoomLinkFail` = `visitRoomLinkFail`;
    title: string = `获取房间连接失败`
}

/**
 * 进入直播间
 */
export class JoinRoomAction extends Action<void>{
    type: `visitJoinRoom` = `visitJoinRoom`;
    title: string = `进入直播间`
}
export class JoinRoomSuccessAction extends Action<void>{
    type: `visitJoinRoomSuccess` = `visitJoinRoomSuccess`;
    title: string = `进入直播间成功`
}
export class JoinRoomFailAction extends Action<void>{
    type: `visitJoinRoomFail` = `visitJoinRoomFail`;
    title: string = `进入直播间失败`
}

export class RoomInfoVisitor extends ActionVisitor {
    visitStart(action: StartAction, ctx: any) {
        return new RoomInfoAction()
    }

    visitRoomInfo(action: RoomInfoAction, ctx: any) {
        const node = createRootAst()
        let liveRoomInfo = getLiveRoomInfo(node)
        let max: number = 10;
        while (!liveRoomInfo && max > 0) {
            const node = createRootAst()
            liveRoomInfo = getLiveRoomInfo(node)
            max -= 1;
            sleep(800)
        }
        if (liveRoomInfo) {
            ctx.roomInfo = liveRoomInfo;
            ctx.currentName = liveRoomInfo.name;
            if (liveRoomInfo.name === ctx.preName) {
                return new NextAction()
            }
            return new RoomInfoSuccessAction()
        } else {
            return new RoomInfoFailAction()
        }
    }

    visitEnd(action: EndAction, ctx: any) {
        return action;
    }

    visitStop(action: StopAction, ctx: any) {
        return action;
    }

    visitRoomInfoSuccess(action: RoomInfoSuccessAction, ctx: any) {
        let roomInfo = ctx.roomInfo;
        let max = 8;
        let success = roomInfo && roomInfo.open
        while (!success && max > 0) {
            const node = createRootAst()
            roomInfo = getLiveRoomInfo(node)
            success = roomInfo && roomInfo.open;
            max -= 1;
            sleep(800)
        }
        if (roomInfo?.open) {
            roomInfo.open()
            ctx.roomInfo = roomInfo;
            return new RedInfoAction()
        } else {
            return new RedInfoFailAction()
        }
    }

    visitRedInfo(action: RedInfoAction, ctx: any) {
        const node = createRootAst()
        const redPackets = getLiveRoomRedPackets(node)
        if (redPackets && redPackets.close) redPackets.close();
        if (redPackets && redPackets.list.length > 0) {
            const reds = redPackets.list.filter(red => {
                if (red.type === `快币`) {
                    return true;
                }
                if (red.type === '口令') {
                    return true;
                }
                if (red.type === `穿云箭`) {
                    return true;
                }
                if (red.type === '粉丝团') {
                    return true;
                }
                if (red.type === '分享') {
                    return true;
                }
                return false;
            }).sort((a, b) => a.count - b.count)
            if (reds.length <= 0) {
                return new RedInfoFailAction();
            }
            ctx.reds = reds;
            return new RedInfoSuccessAction()
        } else {
            return new RedInfoFailAction();
        }
    }

    visitRoomInfoFail(action: RoomInfoFailAction, ctx: any) {
        return new EndAction()
    }

    visitRedInfoSuccess(action: RedInfoSuccessAction, ctx: any) {
        return new RoomLinkAction()
    }
    visitRoomLink(action: RoomLinkAction, ctx: any) {
        const roomLink = getLiveRoomLink(10)
        if (roomLink) {
            const { link, name, obj } = roomLink;
            ctx.link = link;
            ctx.name = name;
            ctx.obj = obj;
            return new RoomLinkSuccessAction()
        }
        return new RoomLinkFailAction()
    }
    visitRoomLinkSuccess(action: RoomLinkSuccessAction, ctx: any) {
        return new EndAction()
    }
    visitRoomLinkFail(action: RoomLinkFailAction, ctx: any) {
        return new EndAction()
    }
    visitRedInfoFail(action: RedInfoFailAction, ctx: any) {
        return new EndAction()
    }
    visitNext(action: NextAction, ctx: any) {
        kwaiLiveaggregatesquare(PACKAGES.KUAI_SHOU);
        return new StartAction()
    }
}
let lastCtx: any;
export function runZhuaBaoTask(follow: boolean = false, extra: any = {}) {
    try {
        // ctx.currentName = liveRoomInfo.name;
        let ctx: any = {
            preName: lastCtx?.currentName
        }
        let action: Action = new StartAction();
        const visitor = new RoomInfoVisitor()
        while (action.type !== `visitEnd`) {
            action = visitor.visitAction(action, ctx)
            sleep(1000)
        }
        if (action.type === 'visitEnd') {
            lastCtx = ctx;
            const { roomInfo, link, reds, name, obj } = ctx;
            extra.name = name;
            if (!roomInfo) {
                return '0';
            };
            const info = (roomInfo as LiveRoomInfo);
            if (follow) info.follow && info.follow();
            if (reds && reds.length > 0) {
                extra.userId = obj?.userId;
                httpPost('addRedPkg', {
                    link,
                    name,
                    online: roomInfo.online,
                    openTime: roomInfo.openTime,
                    readPacketCount: roomInfo.redPacketCount,
                    category: roomInfo.category,
                    rank: roomInfo.rank,
                    uuid: getDeviceUuid(),
                    ...(obj || {}),
                    redPackets: reds.map(red => ({
                        type: red.type,
                        count: red.count,
                        total: red.total,
                        text: red.desc,
                        password: red.password,
                        unit: red.unit,
                        sub_title: red.sub_title,
                        title: red.title,
                        desc: red.desc,
                    }))
                });
                return '1';
            } else {
                return '2';
            }
        }
    } catch (e) {
        log(e.message)
        return '0';
    }
}